var Face = (function () {
    // 表情模块
    var Emoji = {
        index: 0,
        count: 0,
        width: 0,
        speed: 100,
        easing: 0.6
    };

    // 表情描述
    Emoji.faceDesc = [
        "→_→|微笑|嘻嘻|哈哈|爱你|挖鼻|吃惊|晕|泪|馋嘴|抓狂|哼|可爱|怒|汗|害羞|困|钱|偷笑|笑cry|doge|喵喵|酷|衰|闭嘴|鄙视|色|鼓掌",
        "悲伤|思考|生病|亲亲|怒骂|太开心|白眼|右哼哼|左哼哼|嘘|委屈|吐|可怜|睡|挤眼|失望|顶|疑问|困|感冒|拜拜|黑线|阴险|互粉|心|伤心|猪头|熊猫",
        "兔子|握手|作揖|赞|耶|good|弱|no|ok|haha|来|威武|鲜花|钟|浮云|飞机|月亮|太阳|微风|下雨|给力"
    ];

    // 表情结构
    Emoji.faceTpl = '<div id="faceMaskBg"></div>' +
        '<div id="faceBox">' +
        '<div class="faceList"></div>' +
        '<div class="faceHandle"></div>' +
        '</div>';

    // 表情结构渲染
    Emoji.render = function (options) {
        var fragment = document.createDocumentFragment(),
            style = document.createElement("style"),
            div = document.createElement('div'),
            faceItemW = parseInt(window.innerWidth * 0.95),
            faceDesc = Emoji.faceDesc,
            faceBox, faceMaskBg, faceList, faceHandle,
            sty = '', desc = options.desc;
        // 如果添加了新表情描述
        if (desc && desc instanceof Array) faceDesc.concat(desc);
        // 生成dom结构
        div.innerHTML = Emoji.faceTpl;
        // 获取操作dom
        faceBox = div.childNodes[1];
        faceMaskBg = div.childNodes[0];
        faceList = div.querySelector('.faceList');
        faceHandle = div.querySelector('.faceHandle');
        // 渲染子级dom
        faceDesc.forEach(function (strs, i) {
            var faceItem = document.createElement("div"),
                iTag = document.createElement("i"),
                descArr = strs.split("|"),
                iStr = '';
            descArr.forEach(function (str, j) {
                iStr += '<i class="faceicon faceurl' + (i + 1) + ' face' + (j + 1) + '" data-face="[' + str + ']"></i>';
            });
            faceItem.innerHTML = iStr;
            faceItem.className = 'faceItem';
            faceItem.style.width = faceItemW + 'px';
            faceList.appendChild(faceItem);
            faceHandle.appendChild(iTag);
            sty += '.faceicon.faceurl' + (i + 1) + '{background-image: url(' + options.path + '/face-' + (i + 1) + '.png)}\n';
        });
        // 设置滚动参数
        Emoji.width = faceItemW;
        Emoji.count = faceDesc.length;
        // 生成样式结构
        style.innerHTML = sty;
        style.id = 'faceStyle';
        // Emoji.faceStyle = style;
        document.head.appendChild(style);
        // 设置部分dom样式
        faceBox.style.width = faceItemW + 'px';
        faceList.style.width = parseInt(faceItemW * faceDesc.length) + 'px';
        if (!options.shade) faceMaskBg.style.display = 'none';
        // dom结构存入
        fragment.appendChild(faceMaskBg);
        fragment.appendChild(faceBox);
        Emoji.faceDom = fragment;
        // 绑定交互
        Emoji.bind(faceBox, faceMaskBg, options.shadeClose);
    }

    // 绑定交互
    Emoji.bind = function (faceBox, faceMaskBg, shadeClose) {
        // 添加表情点击
        if (shadeClose) {
            faceMaskBg.addEventListener('click', Emoji.hide.bind(this));
        }
        faceBox.addEventListener('click', function (e) {
            var dom = e.target, attrVal;
            if (dom.className.indexOf('faceicon') >= 0) {
                attrVal = dom.getAttribute('data-face');
                Sub.update(attrVal);
                Emoji.hide();
            }
        });
        // 添加表情滑动
        var startX, startY, endX, endY;
        faceBox.addEventListener('touchstart', function (e) {
            startX = e.touches[0].pageX;
            startY = e.touches[0].pageY;
        });
        faceBox.addEventListener('touchend', function (e) {
            endX = e.changedTouches[0].pageX;
            endY = e.changedTouches[0].pageY;
            var dir = Slip.dir(startX, startY, endX, endY),
                faceList = this.querySelector(".faceList"),
                faceHandle = this.querySelector(".faceHandle");
            if (dir == 'left' && Emoji.index < Emoji.count - 1) Emoji.index++;
            if (dir == 'right' && Emoji.index > 0) Emoji.index--;
            if (Slip.isDoing === false) {
                Slip.state(faceHandle, Emoji.index);
                Slip.run(faceList, Emoji.index, Emoji.count, Emoji.width, Emoji.easing, Emoji.speed);
            }
        });
    }

    // 表情显示
    Emoji.show = function (btn) {
        this.index = 0;
        this.position(btn);
        var faceBox = this.faceDom.querySelector("#faceBox"),
            faceList = faceBox.querySelector('.faceList'),
            faceHandle = faceBox.querySelector('.faceHandle');
        faceList.style.left = '0px';
        Slip.state(faceHandle, Emoji.index);
        document.body.appendChild(this.faceDom);
        // document.head.appendChild(this.faceStyle);
    }

    // 表情隐藏
    Emoji.hide = function (params) {
        var fragment = document.createDocumentFragment(),
            faceMaskBg = document.querySelector("#faceMaskBg"),
            faceBox = document.querySelector("#faceBox");
        // faceStyle = document.querySelector("#faceStyle");
        if (!faceMaskBg || !faceBox) return;
        document.body.removeChild(faceMaskBg);
        document.body.removeChild(faceBox);
        // document.head.removeChild(faceStyle);
        fragment.appendChild(faceMaskBg);
        fragment.appendChild(faceBox);
        Emoji.faceDom = fragment;
        // Emoji.faceStyle = faceStyle;
    }

    // 表情位置
    Emoji.position = function (btn) {
        var faceBox = Emoji.faceDom.childNodes[1];
        btnTop = btn.getBoundingClientRect().top + btn.offsetHeight;
        faceBox.style.top = btn.getBoundingClientRect().top + btn.offsetHeight + 10 + 'px';
    }

    // 滑动模块
    var Slip = {
        isDoing: false,
        // 获取滑动方法
        dir: function (startX, startY, endX, endY) {
            var dx = endX - startX,
                dy = startY - endY,
                angle = 0;
            if (Math.abs(dx) < 2 && Math.abs(dy) < 2) {
                return 'none';
            } else {
                angle = Math.atan2(dy, dx) * 180 / Math.PI;
            }
            if (angle >= -45 && angle < 45) return 'right';
            if (angle >= 45 && angle < 135) return 'top';
            if (angle >= -135 && angle < -45) return 'bottom';
            if ((angle >= 135 && angle <= 180) || (angle >= -180 && angle < -135)) return 'left';
        },
        // 进行盒子滑动
        run: function (dom, index, count, width, easing, speed) {
            var dis = index * width;
            var curDis = Math.abs(dom.style.left.replace("px", "") || 0);
            var timer = setInterval(function () {
                if (dis !== curDis) {
                    if (dis > curDis) {
                        curDis += Math.ceil((dis - curDis) * easing);
                    } else {
                        curDis -= Math.ceil((curDis - dis) * easing);
                    }
                    dom.style.left = -curDis + "px";
                } else {
                    clearInterval(timer);
                    Slip.isDoing = false;
                }
            }, speed);
            Slip.isDoing = true;
        },
        // 句柄状态
        state: function (dom, index) {
            var activeI = dom.querySelector('.active');
            if (activeI) activeI.className = '';
            dom.childNodes[index].className = 'active';
        }
    }

    // 绑定触发模块
    var Sub = {
        key: '',
        inputs: {},
        // 绑定触发关系
        bind: function (btn, input) {
            if (this.inputs[btn]) return;
            var btnEl = document.querySelector(btn);
            this.inputs[btn] = document.querySelector(input);
            btnEl.addEventListener('click', function (e) {
                Sub.key = btn;
                Emoji.show(btnEl);
            });
        },
        // 更新表情值
        update: function (value) {
            var input = this.inputs[this.key];
            input.value = input.value + value;
        }
    }

    // 共用api
    return {
        // 初始化
        init: function (options) {
            if (Emoji.faceDom === undefined) {
                Emoji.render({
                    path: options.path,
                    desc: options.desc || [],
                    shade: options.shade || false,
                    shadeClose: options.shadeClose || false
                });
            };
            return this;
        },
        // 给dom添加触发关系
        add: function (btn, input) {
            Sub.bind(btn, input);
            return this;
        },
        // 关闭表情选择
        close: function () {
            Emoji.hide();
        },
        // 扫描节点，渲染表情
        scan: function (value) {
            var faceicon = Emoji.faceDom.querySelectorAll('.faceicon');
            var excstr = ['HTML', 'HEAD', 'META', 'LINK', 'TITLE', 'BODY', 'INPUT', 'TEXTAREA', 'BUTTON', 'SCRIPT', 'STYLE'].join("|");
            var parse = function (elements) {
                var len = elements.length;
                for (var i = 0; i < len; i++) {
                    var element = elements[i];
                    if (excstr.indexOf(element.nodeName) >= 0) {
                        continue;
                    }
                    element.innerHTML = element.innerHTML.replace(/\[([^\[\]]+)\]/g, function (match) {
                        var len = faceicon.length;
                        for (var j = 0; j < len; j++) {
                            var iconEl = faceicon[j],
                                iconName = iconEl.getAttribute('data-face');
                            if (iconName == match) {
                                return '<i class="' + iconEl.className + ' facecss"></i>';
                            }
                        }
                    });
                }
            }
            var elements;
            if (typeof value === 'string') {
                if (value === '*') {
                    elements = document.getElementsByTagName("*");
                } else {
                    elements = document.querySelectorAll(value);
                }
            }
            if (typeof value === 'object') {
                // ...
            }
            parse(elements);
        }
    };
}());